/**
 *
 */
package com.zhengtoon.mctoon.conv.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.qitoon.framework.core.exception.BusinessException;
import com.zhengtoon.mctoon.conv.bean.ConfigDict;
import com.zhengtoon.mctoon.conv.bean.ConvSubject;
import com.zhengtoon.mctoon.conv.bean.session.OrgSessionInfo;
import com.zhengtoon.mctoon.conv.dao.ConvSubjectMapper;
import com.zhengtoon.mctoon.conv.dto.mybatis.Page;
import com.zhengtoon.mctoon.conv.dto.param.UploadInputParam;
import com.zhengtoon.mctoon.conv.dto.request.AddSubjectRequestDto;
import com.zhengtoon.mctoon.conv.dto.request.UpdateSubjectManageDto;
import com.zhengtoon.mctoon.conv.dto.response.*;
import com.zhengtoon.mctoon.conv.exception.ConvPhotoExceptionCode;
import com.zhengtoon.mctoon.conv.service.ConvSubjectService;
import com.zhengtoon.mctoon.conv.utils.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 专题服务 impl实现
 *
 * @author 144637
 * @since 2017-07-14
 * Copyright: Copyright (c) 2017
 * Company:北京政务通科技有限公司
 */
@Service
public class ConvSubjectServiceImpl implements ConvSubjectService {

    private static Logger log = LoggerFactory.getLogger(ConvSubjectServiceImpl.class);

    public static final String SHELVE_SUBJECT_COUNT_LIMIT = SysConfig.getPropertyValue("config.shelve_subject_count_limit"); //上架专题数量限制

    public static final String SUPPORT_FILE_TYPE = SysConfig.getPropertyValue("config.support_file_type"); //支持的上传文件类型

    @Autowired
    private ConvSubjectMapper convSubjectMapper;

    @Override
    public Page getSubjectManageList(Page page) {
        try {
            List<ConvSubject> subjectEntityList = convSubjectMapper.querySubjectManageList(page);
            // 查询数据条数
            Integer dataTotal = convSubjectMapper.querySubjectManageListCount(page);

            List<SubjectManageListDto> manageListDtoList = convertEntityToSubjectManageDtoList(subjectEntityList);

            // 返回参数
            if (dataTotal == null) {
                dataTotal = 0;
            }

            Integer shelveCount = convSubjectMapper.queryShelveCount();
            page.setShelveCount(shelveCount);
            page.setResult(manageListDtoList);
            page.setDataTotal(dataTotal);
            return page;
        } catch (Exception e) {
            log.error("获取专题管理列表错误", e);
            throw new BusinessException(ConvPhotoExceptionCode.GET_SUBJECT_MANAGE_LIST_ERROR);
        }
    }


    @Override
    public int addSubject(AddSubjectRequestDto addSubjectRequestDto, OrgSessionInfo sessionInfo) {
        try {

            ConvSubject subjectEntity = new ConvSubject();
            subjectEntity.setStatus(addSubjectRequestDto.getIsShelve());
            String oldSubjectName = addSubjectRequestDto.getSubjectName();
            subjectEntity.setSubjectName(SubjectCharProcessUtils.getHandledSubjectName(oldSubjectName));
            subjectEntity.setPicUrl(addSubjectRequestDto.getPicUrl());
            subjectEntity.setDetailContent(addSubjectRequestDto.getDetailContent());
            subjectEntity.setHint(addSubjectRequestDto.getHint());
            subjectEntity.setHandleUserId(sessionInfo.getEi());
            subjectEntity.setHandleUserName(sessionInfo.getEn());
            Long currentTime = new Date().getTime();
            subjectEntity.setCreateTime(currentTime);
            subjectEntity.setUpdateTime(currentTime);

            if (AppConstant.SUBJECT_STATUS_SHELVE.equals(addSubjectRequestDto.getIsShelve())
                    && shelveCountOutOfBunds()) {
                return -1;
            }

            // 根据上架状态设置sort字段
            handleSort(subjectEntity, AppConstant.SUBJECT_IS_NOT_EDIT);

            int rs = convSubjectMapper.addSubject(subjectEntity);
            return rs;
        } catch (Exception e) {
            log.error("新增专题错误", e);
            throw new BusinessException(ConvPhotoExceptionCode.ADD_SUBJECT_ERROR);
        }
    }

    /**
     * 判断上架专题数量是否超出限制
     *
     * @return boolean
     * @author 144637
     */
    private boolean shelveCountOutOfBunds() {
        Integer shelveCount = convSubjectMapper.queryShelveCount();

        if (shelveCount == null) {
            shelveCount = 0;
        }

        Integer shelveCountBundsConfig = Integer.valueOf(SHELVE_SUBJECT_COUNT_LIMIT);

        Integer shelveCountBunds;
        if (shelveCountBundsConfig == null) {
            shelveCountBunds = AppConstant.SHELVE_SUBJECT_COUNT_LIMIT_DEFAULT;
        } else {
            shelveCountBunds = shelveCountBundsConfig;
        }

        return shelveCount >= shelveCountBunds;
    }

    @Override
    public int updateSubject(UpdateSubjectManageDto updateSubjectDto, OrgSessionInfo sessionInfo) {
        try {

            ConvSubject subjectEntity = new ConvSubject();
            subjectEntity.setSubjectId(updateSubjectDto.getSubjectId());
            subjectEntity.setStatus(updateSubjectDto.getIsShelve());
            String oldSubjectName = updateSubjectDto.getSubjectName();
            subjectEntity.setSubjectName(SubjectCharProcessUtils.getHandledSubjectName(oldSubjectName));
            subjectEntity.setPicUrl(updateSubjectDto.getPicUrl());
            subjectEntity.setDetailContent(updateSubjectDto.getDetailContent());
            subjectEntity.setHint(updateSubjectDto.getHint());
            subjectEntity.setHandleUserId(sessionInfo.getEi());
            subjectEntity.setHandleUserName(sessionInfo.getEn());
            Long currentTime = new Date().getTime();
            subjectEntity.setUpdateTime(currentTime);

            // 根据上架状态设置sort字段
            handleSort(subjectEntity, AppConstant.SUBJECT_IS_EDIT);

            int rs = convSubjectMapper.updateSubject(subjectEntity);
            return rs;
        } catch (Exception e) {
            log.error("新增专题错误", e);
            throw new BusinessException(ConvPhotoExceptionCode.UPDATE_SUBJECT_ERROR);
        }
    }

    /**
     * 根据上下架状态设置sort的值
     *
     * @param subjectEntity 专题实体
     * @param isEdit        是否编辑
     * @author 144637
     */
    private void handleSort(ConvSubject subjectEntity, boolean isEdit) {
        Integer shelveStatus = subjectEntity.getStatus();
        Integer sortValue = AppConstant.SUBJECT_SORT_VALUE_DEFALUT;
        if (AppConstant.SUBJECT_STATUS_SHELVE.equals(shelveStatus)) {
            boolean isNewShelve = true; // 是否是从未上架到上架
            if (isEdit) {
                ConvSubject oldEntity = convSubjectMapper.querySubjectDetail(subjectEntity.getSubjectId());
                if (AppConstant.SUBJECT_STATUS_SHELVE.equals(oldEntity.getStatus())) { //之前已上架
                    isNewShelve = false;
                }
            }
            if (isNewShelve) {
                Integer presentMaxSort = getShelveMaxSort();
                sortValue = presentMaxSort + 1;
            } else {
                sortValue = null;
            }

        }
        subjectEntity.setSort(sortValue);
    }

    /**
     * 获取上架状态的最大sort
     *
     * @return int
     * @author 144637
     */
    private Integer getShelveMaxSort() {
        Integer maxSort = convSubjectMapper.queryMaxSort();
        if (maxSort == null) {
            return 0;
        }
        return maxSort;
    }

    @Override
    @Transactional
    public int shiftUpSubject(Long subjectId) {

        // 1. 获取当前的sort
        ConvSubject convEntity = convSubjectMapper.querySubjectDetail(subjectId);
        if (AppConstant.SUBJECT_STATUS_NOT_SHELVE.equals(convEntity.getStatus())) {
            throw new BusinessException(ConvPhotoExceptionCode.SUBJECT_NOT_SHELVE);
        }
        Integer currentSort = convEntity.getSort();
        // 2. 获取上一个的sort
        ConvSubject convEntityPrevious = convSubjectMapper.queryPreviousShelveSubjectDetail(subjectId, currentSort);
        if (convEntityPrevious == null) {
            throw new BusinessException(ConvPhotoExceptionCode.SHIFT_SUBJECT_LAST_NULL);
        }
        Integer previousSort = convEntityPrevious.getSort();
        Long previousSubjectId = convEntityPrevious.getSubjectId();

        OrgSessionInfo orgSessionInfo = SessionUtils.getSessionInfo();
        String userId = orgSessionInfo.getEi();
        String userName = orgSessionInfo.getEn();

        // 3. 交换两个的值,更新sort
        Long updateTime = new Date().getTime();
        ConvSubject prevSubject = new ConvSubject();
        prevSubject.setSubjectId(previousSubjectId);
        prevSubject.setSort(currentSort);
        prevSubject.setHandleUserId(userId);
        prevSubject.setHandleUserName(userName);
        prevSubject.setUpdateTime(updateTime);
        int previousRow = convSubjectMapper.updateSortBySubjectId(prevSubject);

        ConvSubject currentSubject = new ConvSubject();
        currentSubject.setSubjectId(subjectId);
        currentSubject.setSort(previousSort);
        currentSubject.setHandleUserId(userId);
        currentSubject.setHandleUserName(userName);
        currentSubject.setUpdateTime(updateTime);
        int row = convSubjectMapper.updateSortBySubjectId(currentSubject);

        return previousRow + row;
    }

    /**
     * 上下架
     *
     * @param subjectId
     * @param status
     * @return
     */
    @Override
    public Integer shelveOrUnshelveSubject(Long subjectId, Integer status) {
        try {
            ConvSubject convSubject = new ConvSubject();
            Integer sort;
            if (AppConstant.SUBJECT_STATUS_NOT_SHELVE.equals(status)) {
                sort = AppConstant.SUBJECT_SORT_VALUE_DEFALUT;
            } else {
                if (shelveCountOutOfBunds()) {
                    return -1;
                }
                sort = getShelveMaxSort() + 1;
            }

            OrgSessionInfo sessionInfo = SessionUtils.getSessionInfo();
            String userId = sessionInfo.getEi();
            String userName = sessionInfo.getEn();

            Long updateTime = new Date().getTime();

            convSubject.setSubjectId(subjectId);
            convSubject.setStatus(status);
            convSubject.setHandleUserId(userId);
            convSubject.setHandleUserName(userName);
            convSubject.setSort(sort);
            convSubject.setUpdateTime(updateTime);


            int i = convSubjectMapper.shelveOrUnshelveSubject(convSubject);

            return i;
        } catch (Exception e) {
            log.error("上下架错误", e);
            throw new BusinessException(ConvPhotoExceptionCode.SHELVE_OR_UN_SHELVE_SUBJECT_ERROR);
        }
    }

    @Override
    public UploadImgDto uploadImg(UploadInputParam uploadInputParam) {

        if (!fileTypeSupport(uploadInputParam.getFileType())) {
            throw new BusinessException(ConvPhotoExceptionCode.UNSUPPORTED_FILE_TYPE);
        }
        String url = CloudAppUtils.getPublicUrlOfSubject(uploadInputParam);
        UploadImgDto uploadImgDto = new UploadImgDto();
        uploadImgDto.setUrl(url);
        return uploadImgDto;
    }

    /**
     * 文件类型是否支持
     *
     * @param fileType 文件类型后缀
     * @return boolean
     * <p>
     * author 144637
     */
    private boolean fileTypeSupport(String fileType) {
        fileType = fileType.toLowerCase();
        List<ConfigDict> supprotFileTypes = JSON.parseObject(SUPPORT_FILE_TYPE, new TypeReference<List<ConfigDict>>() {
        });
        for (ConfigDict item : supprotFileTypes) {
            if (fileType.endsWith(item.getDictValue())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public SubjectManageDetailDto queryManageSubjectDetail(Long subjectId) {
        try {
            ConvSubject entity = convSubjectMapper.querySubjectDetail(subjectId);
            SubjectManageDetailDto subjectDetailDto = convertEntityToSubjectManageDetailDto(entity);
            return subjectDetailDto;
        } catch (Exception e) {
            log.error("获取专题详情错误", e);
            throw new BusinessException(ConvPhotoExceptionCode.GET_SUBJECT_DETAIL_ERROR);
        }
    }

    @Override
    public List<SlideshowListDto> getSlideshowList() {
        try {
            List<ConvSubject> entityList = convSubjectMapper.getSlideshowList();

            List<SlideshowListDto> dtoList = convertToSlideshowDtoList(entityList);

            return dtoList;
        } catch (Exception e) {
            log.error("获取轮播列表错误", e);
            throw new BusinessException(ConvPhotoExceptionCode.GET_SLIDE_SHOW_LIST_ERROR);
        }

    }

    @Override
    public SubjectDetailDto querySubjectDetail(Long subjectId) {
        try {
            ConvSubject entity = convSubjectMapper.querySubjectDetail(subjectId);
            SubjectDetailDto subjectDetailDto = convertEntityToSubjectDetailDto(entity);
            return subjectDetailDto;
        } catch (Exception e) {
            log.error("获取专题详情错误", e);
            throw new BusinessException(ConvPhotoExceptionCode.GET_SUBJECT_DETAIL_ERROR);
        }
    }

    /**
     * entity==>dto list 轮播图列表
     *
     * @param entityList subject实体
     * @return List<SlideshowListDto>
     * @author 144637
     */
    private List<SlideshowListDto> convertToSlideshowDtoList(List<ConvSubject> entityList) {
        List<SlideshowListDto> dtoList = new ArrayList<>();
        for (ConvSubject entity : entityList) {
            SlideshowListDto dto = new SlideshowListDto();
            dto.setPicUrl(entity.getPicUrl());
            dto.setSubjectId(entity.getSubjectId().toString());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * entity==>dto 专题详情
     *
     * @param entity subject实体
     * @return SubjectDetailDto
     * @author 144637
     */
    private SubjectDetailDto convertEntityToSubjectDetailDto(ConvSubject entity) {
        SubjectDetailDto dto = new SubjectDetailDto();
        dto.setPicUrl(entity.getPicUrl());
        dto.setDetailContent(entity.getDetailContent());
        dto.setHint(entity.getHint());
        dto.setSubjectName(entity.getSubjectName());
        dto.setIsShelve(entity.getStatus());
        return dto;
    }

    /**
     * 获取专题字典详情
     *
     * @param subjectEntityNameList
     * @return
     */
    private List<SubjectNameListDto> convertEntityToSubjectNameDtoList(List<ConvSubject> subjectEntityNameList) {
        List<SubjectNameListDto> dtoList = new ArrayList<>();
        for (ConvSubject entity : subjectEntityNameList) {
            SubjectNameListDto dto = new SubjectNameListDto();
            dto.setSubjectId(entity.getSubjectId());
            dto.setSubjectName(entity.getSubjectName());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 专题字典项
     */
    public List<SubjectNameListDto> getSubjectNameList() {
        try {
            List<ConvSubject> subjectNames = convSubjectMapper.getSubjectNameList();
            List<SubjectNameListDto> subjectNameList = convertEntityToSubjectNameDtoList(subjectNames);
            return subjectNameList;
        } catch (Exception e) {
            log.error(" 获取字典项失败 ", e);
            throw new BusinessException(ConvPhotoExceptionCode.AUDIT_CONFIG_ERROR);
        }
    }


    /**
     * entity==>dto 管理端专题详情
     *
     * @param entity subject实体
     * @return SubjectDetailDto
     * @author 144637
     */
    private SubjectManageDetailDto convertEntityToSubjectManageDetailDto(ConvSubject entity) {
        SubjectManageDetailDto dto = new SubjectManageDetailDto();
        dto.setPicUrl(entity.getPicUrl());
        dto.setDetailContent(entity.getDetailContent());
        dto.setHint(entity.getHint());
        dto.setSubjectName(entity.getSubjectName());
        dto.setIsShelve(entity.getStatus());
        return dto;
    }

    /**
     * entity==>dto list 专题管理列表
     *
     * @param subjectEntityList 专题实体列表
     * @return List<SubjectManageListDto>
     * @author 144637
     */
    private List<SubjectManageListDto> convertEntityToSubjectManageDtoList(List<ConvSubject> subjectEntityList) {
        List<SubjectManageListDto> dtoList = new ArrayList<>();
        for (ConvSubject entity : subjectEntityList) {
            SubjectManageListDto dto = new SubjectManageListDto();
            dto.setSubjectId(entity.getSubjectId().toString());
            dto.setSubjectName(entity.getSubjectName());
            dto.setPicUrl(entity.getPicUrl());
            dto.setHandleUserName(entity.getHandleUserName());
            dto.setStatus(entity.getStatus());
            dto.setUpdateTime(DateFormatAppUtils.getFormatDate(entity.getUpdateTime()));

            dtoList.add(dto);
        }

        return dtoList;
    }


}